/* $Header: p_calib.c,v 2.2 01/10/02 10:27:46 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: calib                                                  */
/* ============                                                        */
/*                                                                     */
/* Author: wikfors                                                     */
/*                                                                     */
/* MODULE PURPOSE:  apply sensor calibrations to setpoints before      */
/*  transfer to the pcb and to actuals before they are used.           */
/*  With this scheme, all tables represent ideal conditions, and       */
/*  any unique sensor behavior is isolated here.                       */
/*                                                                     */
/***********************************************************************/

/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <error.h>
#include <p_wkfile.h>
#include <p_status.h>
#include <math.h>
#include <list_mgmt.h>
#include <pcb_defs.h>
#include <clock_ui.h>
#include <exception.h>
#include <err_handler.h>
#include <keyboard.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "proto.h"
#include "p_tcomp.h"

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/


#define MAX_PRES_SPAN_DRIFT_PERCENTAGE  10
#define MAX_FLOW_SPAN_DRIFT_PERCENTAGE  10
#define MAX_FRIT_SPAN_DRIFT_PERCENTAGE  20

#define MIN_FLOW_OFFSET_COUNTS_ABSOLUTE   327   /*  25mV absolute in counts */
#define MAX_FLOW_OFFSET_COUNTS_RELATIVE  9174   /* 700mV relative to calib offset in counts */

#define MAX_PRES_OFFSET_DRIFT_PERCENTAGE 4  /* of span! */
#define MAX_FRIT_OFFSET_DRIFT_PERCENTAGE 4  /* of span! */


#define MIN_PRES_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100-MAX_PRES_SPAN_DRIFT_PERCENTAGE)/100)
#define MIN_FLOW_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100-MAX_FLOW_SPAN_DRIFT_PERCENTAGE)/100)
#define MIN_FRIT_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100-MAX_FRIT_SPAN_DRIFT_PERCENTAGE)/100)

#define MAX_PRES_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100+MAX_PRES_SPAN_DRIFT_PERCENTAGE)/100)
#define MAX_FLOW_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100+MAX_FLOW_SPAN_DRIFT_PERCENTAGE)/100)
#define MAX_FRIT_GAIN (U_INT16)(CALIB_GAIN_SCALING*(100+MAX_FRIT_SPAN_DRIFT_PERCENTAGE)/100)


 /* minimum percentages of max range for upper calibration point */

#define PRES_SENSOR_SPAN_PERCENTAGE 70
#define FLOW_SENSOR_SPAN_PERCENTAGE 50
#define FRIT_FLOW_SPAN_PERCENTAGE   70


/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/
/**begin_proto**/

#pragma SECTION PROG=rom3

/**end_proto**/



/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

INT32 GetFritOffsetDispUnits( INT16 offset, U_INT16 temp, U_INT16 atm_pres, pDET_GAS gas_table )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;
    U_INT32 flow;
    pPRES_SENSOR_STRUCT sensor;
    pFRIT_STRUCT frit;

    sensor = &gas_table->Tcomp_Tables->Pres_Sensor;
    frit   = &gas_table->Tcomp_Tables->Frit;

    predicted = CalcPredictedPsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToPres    ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       flow = FritPresToFlow ( pres, frit, temp, atm_pres );
       return -(INT32)ConvertFlowIuToDisplay ( flow, gas_table->IU_Scaling );
    }
    else
    {
       pres =  VoltsToPres ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       flow = FritPresToFlow ( pres, frit, temp, atm_pres );
       return  (INT32)ConvertFlowIuToDisplay ( flow, gas_table->IU_Scaling );
    }

}


/**begin_proto**/

INT32 GetFritOffsetDcUnits( INT16 offset, U_INT16 temp, U_INT16 atm_pres, pDET_GAS gas_table )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;
    U_INT32 flow;
    pPRES_SENSOR_STRUCT sensor;
    pFRIT_STRUCT frit;

    sensor = &gas_table->Tcomp_Tables->Pres_Sensor;
    frit   = &gas_table->Tcomp_Tables->Frit;

    predicted = CalcPredictedPsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToPres    ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       flow = FritPresToFlow ( pres, frit, temp, atm_pres );
       return -(INT32)ConvertFlowIuToDcu ( flow, gas_table->IU_Scaling );
    }
    else
    {
       pres =  VoltsToPres ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       flow = FritPresToFlow ( pres, frit, temp, atm_pres );
       return  (INT32)ConvertFlowIuToDcu ( flow, gas_table->IU_Scaling );
    }

}


/**begin_proto**/

INT32 GetMaxFritOffset( U_INT16 temp, pDET_GAS gas_table)

/**end_proto**/
{
     INT16 delta_T;
     U_INT16 span;
     pPRES_SENSOR_STRUCT sensor;

     sensor = &gas_table->Tcomp_Tables->Pres_Sensor;

     delta_T = ( temp - (U_INT16)TCOMP_STD_TEMP_IU );

     span   = sensor->Parms.Span   + delta_T * sensor->Parms.dSpan_dT   / PS_dT_SCALING;

     return QuadWordMultiplyDivide( span, MAX_FRIT_OFFSET_DRIFT_PERCENTAGE, 100 );

}

/**begin_proto**/

UI_ERR ValidateFritOffset( INT16 offset, U_INT16 temp, U_INT16 atm_pres, pDET_GAS  gas_table )

/**end_proto**/
{
     (void) atm_pres;

     if ( offset < 0 )
     {
          offset = - offset;
     }

     if ( GetMaxFritOffset( temp, gas_table ) < offset ) return EXCEEDS_CALIB_RANGE;

     return OK;
}

/**begin_proto**/

INT16 CalcFritCalibOffset ( U_INT16 measured, pDET_GAS  gas_table, U_INT16 temp )

/**end_proto**/
{
     return  SubtractAdcOffset(measured) - CalcPredictedPsOffsetIu( &gas_table->Tcomp_Tables->Pres_Sensor, temp );
}

/**begin_proto**/

U_INT32 GetFritFlowRequiredToCalibrate( pFRIT_STRUCT frit )

/**end_proto**/
{

    return QuadWordMultiplyDivide( frit->Parms.Max_Flow, FRIT_FLOW_SPAN_PERCENTAGE, 100 );
}

/**begin_proto**/

BIT8 EnoughFritFlowToCalibrate ( U_INT32 flow, pFRIT_STRUCT frit, U_INT32 IU_Scaling )

/**end_proto**/
{

    return ConvertFlowIuToDisplay( flow, IU_Scaling )
        >= ConvertFlowIuToDisplay( GetFritFlowRequiredToCalibrate( frit ), IU_Scaling );
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

INT32 GetFlowOffsetDispUnits( INT16 offset, U_INT32 IU_Scaling, pFLOW_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;

    predicted = GetInletPredictedFsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToFlow ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return -(INT32)ConvertFlowIuToDisplay ( pres, IU_Scaling );
    }
    else
    {
       pres =  VoltsToFlow ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return  (INT32)ConvertFlowIuToDisplay ( pres, IU_Scaling );
    }

}


/**begin_proto**/

INT32 GetFlowOffsetDcUnits( INT16 offset, U_INT32 IU_Scaling, pFLOW_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;

    predicted = GetInletPredictedFsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToFlow ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return -(INT32)ConvertFlowIuToDcu ( pres, IU_Scaling );
    }
    else
    {
       pres =  VoltsToFlow ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return  (INT32)ConvertFlowIuToDcu ( pres, IU_Scaling );
    }

}


/**begin_proto**/

INT16 GetMinFlowOffset( pFLOW_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{

    return  ( MIN_FLOW_OFFSET_COUNTS_ABSOLUTE - GetInletPredictedFsOffsetIu( sensor, temp ) );

}

/**begin_proto**/

INT16 GetMaxFlowOffset( void )

/**end_proto**/
{

    return MAX_FLOW_OFFSET_COUNTS_RELATIVE;

}

/**begin_proto**/

UI_ERR ValidateFlowOffset( INT16 offset, U_INT32 IU_Scaling, pFLOW_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
     (void) IU_Scaling;

     if (( GetMinFlowOffset( sensor, temp ) > offset ) ||
         ( GetMaxFlowOffset(              ) < offset )) return EXCEEDS_CALIB_RANGE;

     return OK;

}


/**begin_proto**/

INT16 CalcFlowCalibOffset ( U_INT16 measured, pINLET_STATUS status, U_INT16 temp )

/**end_proto**/
{
#if 1


#define SCALING      16384

     U_INT16 delta;
     INT16 old_offset;
     U_INT16 reading;
     U_INT32 mult;
     U_INT16   low_bound;
     U_INT16   high_bound;
     pFLOW_SENSOR_STRUCT sensor;


     sensor = &( status->Tcomp_Tables->Flow_Sensor );


         /* bounds are in counts for .2 and 1.25 mL/min flow */
         /* remember alpha * beta is the slope of the flow/volts */
         /* curve (counts/ml) at the zero point                  */

     COOKIE = low_bound  = (U_INT16) (0.2  *  sensor->Parms.Alpha_Low * sensor->Parms.Beta_Low );

     COOKIE = high_bound = (U_INT16) (1.25 *  sensor->Parms.Alpha_Low * sensor->Parms.Beta_Low );

     COOKIE = reading = SubtractAdcOffset( measured );

     COOKIE = old_offset = GetInletPredictedFsOffsetIu( sensor, temp ) + status->Calib.F_Sensor_Offset;

     if ( reading >  old_offset )
     {
        COOKIE = delta = reading - old_offset;
     }
     else
     {
        COOKIE = delta = old_offset - reading;
     }

     if       ( delta < low_bound  )  mult = 0 * SCALING;
     else if  ( delta > high_bound )  mult = 1 * SCALING;
     else                             mult = ( ( delta - low_bound ) * (U_INT32)SCALING ) / high_bound;

     COOKIE = mult;

     COOKIE = ( mult * reading - mult * old_offset )/ SCALING + status->Calib.F_Sensor_Offset;

     return COOKIE;

#else
     return  SubtractAdcOffset(measured) - GetInletPredictedFsOffsetIu( sensor, temp );
#endif
}

/**begin_proto**/

U_INT32 GetFlowRequiredToCalibrate( pFLOW_SENSOR_STRUCT sensor )

/**end_proto**/
{

    return QuadWordMultiplyDivide( sensor->Parms.Max_Flow, FLOW_SENSOR_SPAN_PERCENTAGE, 100 );
}

/**begin_proto**/

BIT8 EnoughFlowToCalibrate ( U_INT32 flow, pFLOW_SENSOR_STRUCT sensor, U_INT32 IU_Scaling )

/**end_proto**/
{

    return ConvertFlowIuToDisplay( flow, IU_Scaling )
        >= ConvertFlowIuToDisplay( GetFlowRequiredToCalibrate( sensor ), IU_Scaling );
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

INT32 GetPresOffsetDispUnits( INT16 offset, U_INT16 Dcm2_Per_IU, pPRES_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;

    predicted = CalcPredictedPsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToPres ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return -(INT32)ConvertPresIuToDisplay ( pres, Dcm2_Per_IU );
    }
    else
    {
       pres =  VoltsToPres ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return  (INT32)ConvertPresIuToDisplay ( pres, Dcm2_Per_IU );
    }

}


/**begin_proto**/

INT32 GetPresOffsetDcUnits( INT16 offset, U_INT16 Dcm2_Per_IU, pPRES_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
    U_INT16 predicted;
    U_INT16 pres;

    predicted = CalcPredictedPsOffsetIu( sensor, temp );

    if ( offset < 0)
    {
       pres = VoltsToPres ( AddAdcOffset( predicted - offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return -(INT32)ConvertPresIuToDcu ( pres, Dcm2_Per_IU );
    }
    else
    {
       pres =  VoltsToPres ( AddAdcOffset( predicted + offset ), sensor, temp, 0, CALIB_GAIN_SCALING );
       return  (INT32)ConvertPresIuToDcu ( pres, Dcm2_Per_IU );
    }

}


/**begin_proto**/

INT16 GetMaxPresOffset( pPRES_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{
     INT16 delta_T;
     U_INT16 span;

     delta_T = ( temp - (U_INT16)TCOMP_STD_TEMP_IU );

     span   = sensor->Parms.Span   + delta_T * sensor->Parms.dSpan_dT   / PS_dT_SCALING;

     return QuadWordMultiplyDivide( span, MAX_PRES_OFFSET_DRIFT_PERCENTAGE, 100 );

}

/**begin_proto**/

UI_ERR ValidatePresOffset( INT16 offset, U_INT16 Dcm2_Per_IU, pPRES_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{

     (void) Dcm2_Per_IU;

     if ( offset < 0 )
     {
          offset = - offset;
     }

     if ( GetMaxPresOffset( sensor, temp ) < offset ) return EXCEEDS_CALIB_RANGE;

     return OK;

}

/**begin_proto**/

INT16 CalcPresCalibOffset ( U_INT16 measured, pPRES_SENSOR_STRUCT sensor, U_INT16 temp )

/**end_proto**/
{

     return  SubtractAdcOffset(measured) - CalcPredictedPsOffsetIu( sensor, temp );

}

/**begin_proto**/

U_INT16 GetPresRequiredToCalibrate( pPRES_SENSOR_STRUCT sensor )

/**end_proto**/
{

    return QuadWordMultiplyDivide( sensor->Parms.Range, PRES_SENSOR_SPAN_PERCENTAGE, 100 );
}

/**begin_proto**/

BIT8 EnoughPresToCalibrate ( U_INT16 pres, pPRES_SENSOR_STRUCT sensor, U_INT16 Dcm2_Per_IU )

/**end_proto**/
{

    return ConvertPresIuToDisplay( pres, Dcm2_Per_IU )
        >= ConvertPresIuToDisplay( GetPresRequiredToCalibrate( sensor ), Dcm2_Per_IU );
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

U_INT16 CalcCalibGain ( U_INT32 current_value, U_INT32 measured_value, U_INT16 gain )

/**end_proto**/
{
    return QuadWordMultiplyDivide( gain, current_value, measured_value );
}

/**begin_proto**/

UI_ERR ValidatePresCalibGain ( U_INT16 gain )

/**end_proto**/
{
    if (( gain < MIN_PRES_GAIN ) || ( gain > MAX_PRES_GAIN )) return EXCEEDS_CALIB_RANGE;

    return OK;
}

/**begin_proto**/

UI_ERR ValidateFlowCalibGain ( U_INT16 gain )

/**end_proto**/
{
    if (( gain < MIN_FLOW_GAIN ) || ( gain > MAX_FLOW_GAIN )) return EXCEEDS_CALIB_RANGE;

    return OK;
}

/**begin_proto**/

UI_ERR ValidateFritCalibGain ( U_INT16 gain )

/**end_proto**/
{
    if (( gain < MIN_FRIT_GAIN ) || ( gain > MAX_FRIT_GAIN )) return EXCEEDS_CALIB_RANGE;

    return OK;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 WriteUserCalib ( U_INT8 module_number, pCALIB_STRUCT calib )

/**end_proto**/
{

     BIT8 result;

     result = TRUE;

     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)INVALID_USER_CALIB );

     SetDateTime( &calib->Date );

     result &= WriteUserCalibDate( module_number, calib->Date );

     result &= WriteEeprom( module_number, USER_POS_1_OFFSET, calib->Pos_1.Offset );
     result &= WriteEeprom( module_number, USER_POS_1_GAIN,   calib->Pos_1.Gain );
     result &= WriteEeprom( module_number, USER_POS_1_VALUE,  calib->Pos_1.Value );

     result &= WriteEeprom( module_number, USER_POS_2_OFFSET, calib->Pos_2.Offset );
     result &= WriteEeprom( module_number, USER_POS_2_GAIN,   calib->Pos_2.Gain );
     result &= WriteEeprom( module_number, USER_POS_2_VALUE,  calib->Pos_2.Value );

     result &= WriteEeprom( module_number, USER_POS_3_OFFSET, calib->Pos_3.Offset );
     result &= WriteEeprom( module_number, USER_POS_3_GAIN,   calib->Pos_3.Gain );
     result &= WriteEeprom( module_number, USER_POS_3_VALUE,  calib->Pos_3.Value );


     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)USER_ENABLED );

     return result;
}


/**begin_proto**/

BIT8 WriteUserCalibDisabled ( U_INT8 module_number )

/**end_proto**/
{
    return WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)USER_DISABLED );
}


/**begin_proto**/

BIT8 WriteUserCalibEnabled ( U_INT8 module_number )

/**end_proto**/
{
    return WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)USER_ENABLED );
}


/**begin_proto**/

BIT8 ReadUserCalib ( U_INT8 module_number, pCALIB_STRUCT calib )

/**end_proto**/
{
     BIT8 result;

     result = TRUE;

     ReadCalibDate( module_number, &calib->Date );

     result &= ReadEeprom( module_number, USER_POS_1_OFFSET, (U_INT16 *)&calib->Pos_1.Offset );
     result &= ReadEeprom( module_number, USER_POS_1_GAIN,   (U_INT16 *)&calib->Pos_1.Gain );
     result &= ReadEeprom( module_number, USER_POS_1_VALUE,  (U_INT16 *)&calib->Pos_1.Value );

     result &= ReadEeprom( module_number, USER_POS_2_OFFSET, (U_INT16 *)&calib->Pos_2.Offset );
     result &= ReadEeprom( module_number, USER_POS_2_GAIN,   (U_INT16 *)&calib->Pos_2.Gain );
     result &= ReadEeprom( module_number, USER_POS_2_VALUE,  (U_INT16 *)&calib->Pos_2.Value );

     result &= ReadEeprom( module_number, USER_POS_3_OFFSET, (U_INT16 *)&calib->Pos_3.Offset );
     result &= ReadEeprom( module_number, USER_POS_3_GAIN,   (U_INT16 *)&calib->Pos_3.Gain );
     result &= ReadEeprom( module_number, USER_POS_3_VALUE,  (U_INT16 *)&calib->Pos_3.Value );


     return result;
}

/**begin_proto**/

BIT8 WriteFactoryCalib ( U_INT8 module_number, pCALIB_STRUCT calib )

/**end_proto**/
{
     BIT8 result;

     result = TRUE;

     result &= WriteEeprom( module_number, FACTORY_POS_1_OFFSET, calib->Pos_1.Offset );
     result &= WriteEeprom( module_number, FACTORY_POS_1_GAIN,   calib->Pos_1.Gain );

     result &= WriteEeprom( module_number, FACTORY_POS_2_OFFSET, calib->Pos_2.Offset );
     result &= WriteEeprom( module_number, FACTORY_POS_2_GAIN,   calib->Pos_2.Gain );

     result &= WriteEeprom( module_number, FACTORY_POS_3_OFFSET, calib->Pos_3.Offset );
     result &= WriteEeprom( module_number, FACTORY_POS_3_GAIN,   calib->Pos_3.Gain );

     return result;
}

/**begin_proto**/

BIT8 WriteFactoryPos1Offset ( U_INT8 module_number, INT16 offset )

/**end_proto**/
{
     return WriteEeprom( module_number, FACTORY_POS_1_OFFSET, offset );
}

/**begin_proto**/

BIT8 WriteUserPos2Offset ( U_INT8 module_number, INT16 offset )

/**end_proto**/
{
     BIT8 result;

     result = TRUE;

     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)INVALID_USER_CALIB );
     result &= WriteEeprom( module_number, USER_POS_2_OFFSET, offset );
     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)USER_ENABLED );

     return result;
}

/**begin_proto**/

BIT8 ReadFactoryCalib ( U_INT8 module_number, pCALIB_STRUCT calib )

/**end_proto**/
{

     BIT8 result;

     result = TRUE;

     /* revisit: check gain for zero, to avoid fatal divides, this should really */
     /* be done as a silent upgrade to initialize the factory gain field to !0   */

     result &= ReadEeprom( module_number, FACTORY_POS_1_OFFSET, (U_INT16 *)&calib->Pos_1.Offset );
     result &= ReadEeprom( module_number, FACTORY_POS_1_GAIN,   (U_INT16 *)&calib->Pos_1.Gain );
     if ( calib->Pos_1.Gain == 0 ) calib->Pos_1.Gain = CALIB_GAIN_SCALING;
     calib->Pos_1.Value = 0;

     result &= ReadEeprom( module_number, FACTORY_POS_2_OFFSET, (U_INT16 *)&calib->Pos_2.Offset );
     result &= ReadEeprom( module_number, FACTORY_POS_2_GAIN,   (U_INT16 *)&calib->Pos_2.Gain );
     if ( calib->Pos_2.Gain == 0 ) calib->Pos_2.Gain = CALIB_GAIN_SCALING;
     calib->Pos_2.Value = 0;

     result &= ReadEeprom( module_number, FACTORY_POS_3_OFFSET, (U_INT16 *)&calib->Pos_3.Offset );
     result &= ReadEeprom( module_number, FACTORY_POS_3_GAIN,   (U_INT16 *)&calib->Pos_3.Gain );
     if ( calib->Pos_3.Gain == 0 ) calib->Pos_3.Gain = CALIB_GAIN_SCALING;
     calib->Pos_3.Value = 0;

     ReadCalibDate( module_number, &calib->Date );

     return result;
}

/**begin_proto**/

BIT8 ScratchUserCalib ( U_INT8 module_number )

/**end_proto**/
{

     CALIB_STRUCT calib;
     BIT8         result;
     DATETIME     date;

     result = TRUE;

     calib.Pos_1.Offset = 0;
     calib.Pos_2.Offset = 0;
     calib.Pos_3.Offset = 0;

     calib.Pos_1.Gain    = CALIB_GAIN_SCALING;   /* 1, unity gain */
     calib.Pos_2.Gain    = CALIB_GAIN_SCALING;   /* 1, unity gain */
     calib.Pos_3.Gain    = CALIB_GAIN_SCALING;   /* 1, unity gain */

     calib.Pos_1.Value  = 0;
     calib.Pos_2.Value  = 0;
     calib.Pos_3.Value  = 0;


     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)INVALID_USER_CALIB );


     InitializeDateTime( &date );
     result &= WriteUserCalibDate( module_number, date );


     result &= WriteEeprom( module_number, USER_POS_1_OFFSET, calib.Pos_1.Offset );
     result &= WriteEeprom( module_number, USER_POS_1_GAIN,   calib.Pos_1.Gain );
     result &= WriteEeprom( module_number, USER_POS_1_VALUE,  calib.Pos_1.Value );

     result &= WriteEeprom( module_number, USER_POS_2_OFFSET, calib.Pos_2.Offset );
     result &= WriteEeprom( module_number, USER_POS_2_GAIN,   calib.Pos_2.Gain );
     result &= WriteEeprom( module_number, USER_POS_2_VALUE,  calib.Pos_2.Value );

     result &= WriteEeprom( module_number, USER_POS_3_OFFSET, calib.Pos_3.Offset );
     result &= WriteEeprom( module_number, USER_POS_3_GAIN,   calib.Pos_3.Gain );
     result &= WriteEeprom( module_number, USER_POS_3_VALUE,  calib.Pos_3.Value );

     result &= WriteEeprom( module_number, USER_CALIB_STATE, (U_INT16)FACTORY );

     return result;
}

/**begin_proto**/

void ReadCalibDate ( U_INT8 module_number, DATETIME *calib_date )

/**end_proto**/
{
     union {  U_INT32                   date_long;
              struct { U_INT16 word1;
                       U_INT16 word2; } date;
           } when;

    BIT8 result;

    result = TRUE;

    InitializeDateTime( calib_date );

    if ( ReadCalibState( module_number ) == USER_ENABLED )
    {
        result &= ReadEeprom( module_number, USER_CALIB_DATE1, &when.date.word1 );
        result &= ReadEeprom( module_number, USER_CALIB_DATE2, &when.date.word2 );

        if (result)
        {
              /* revisit - calib is trash! what do we do now */

              *calib_date = TimeFromSeconds ( when.date_long );
        }
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

BIT8 ReadAutoCalOffset ( pINLET_STATUS status, pCALIB_STRUCT calib )

/**end_proto**/
{

      BIT8 result;

      switch ( status->Config->Gas_Type )
      {
         case N2: result = ReadEeprom( status->Module_Number, N2_AUTO_CAL_OFFSET, (U_INT16 *) &calib->Pos_2.Offset );
                  break;
         case H2: result = ReadEeprom( status->Module_Number, H2_AUTO_CAL_OFFSET, (U_INT16 *) &calib->Pos_2.Offset );
                  break;
         case He: result = ReadEeprom( status->Module_Number, He_AUTO_CAL_OFFSET, (U_INT16 *) &calib->Pos_2.Offset );
                  break;
         case ArMe: result = ReadEeprom( status->Module_Number, ArMe_AUTO_CAL_OFFSET, (U_INT16 *) &calib->Pos_2.Offset );
                  break;
         default: result = ReadEeprom( status->Module_Number, Unused_AUTO_CAL_OFFSET_1, (U_INT16 *) &calib->Pos_2.Offset );
                  break;
      }

      return result;
}

/**begin_proto**/

BIT8 SaveAutoCalOffset ( pINLET_STATUS status, INT16 offset )

/**end_proto**/
{

      BIT8 result;

      switch ( status->Config->Gas_Type )
      {
         case N2: result = WriteEeprom( status->Module_Number, N2_AUTO_CAL_OFFSET, (U_INT16)offset );
                  break;
         case H2: result = WriteEeprom( status->Module_Number, H2_AUTO_CAL_OFFSET, (U_INT16)offset );
                  break;
         case He: result = WriteEeprom( status->Module_Number, He_AUTO_CAL_OFFSET, (U_INT16)offset );
                  break;
         case ArMe: result = WriteEeprom( status->Module_Number, ArMe_AUTO_CAL_OFFSET, (U_INT16)offset );
                  break;
         default: result = WriteEeprom( status->Module_Number, Unused_AUTO_CAL_OFFSET_1, (U_INT16)offset );
                  break;
      }

      return result;
}

/**begin_proto**/

BIT8 WriteUserCalibDate ( U_INT8 module_number, DATETIME date )

/**end_proto**/
{
     union {  U_INT32                   date_long;
              struct { U_INT16 word1;
                       U_INT16 word2; } date;
           } when;

     BIT8 result;

     result = TRUE;

     when.date_long = SecondsSince1980( date );

     result &= WriteEeprom( module_number, USER_CALIB_DATE1, when.date.word1 );
     result &= WriteEeprom( module_number, USER_CALIB_DATE2, when.date.word2 );

     return result;
}

/**begin_proto**/

CALIB_STATE  ReadCalibState ( U_INT8 module_number )

/**end_proto**/
{

   U_INT16 data;

   if ( !ReadEeprom( module_number, USER_CALIB_STATE, &data ) )
   {
       data = (U_INT16)FACTORY;
   }

   return (CALIB_STATE)data;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void TrashModule ( U_INT8 module )

/**end_proto**/
{

   static const EXCEPTION Bad_Module[] = { FI_IO_FAILURE, BI_IO_FAILURE, FD_IO_FAILURE, BD_IO_FAILURE, PA_IO_FAILURE };

   SetException( Bad_Module[ module ] );

   switch ( module )
   {
       case FRNT_INLET_MODULE_NUMBER :  Inst_Config.Pneu.Frnt_Inlet.Functional = FALSE;
                                        break;

       case BACK_INLET_MODULE_NUMBER :  Inst_Config.Pneu.Back_Inlet.Functional = FALSE;
                                        break;

       case FRNT_DETECTOR_MODULE_NUMBER:Inst_Config.Pneu.Frnt_Detector.Functional = FALSE;
                                        break;

       case BACK_DETECTOR_MODULE_NUMBER:Inst_Config.Pneu.Back_Detector.Functional = FALSE;
                                        break;

       case PNEU_AUX_MODULE_NUMBER :    Inst_Config.Pneu.Aux_3.Functional = FALSE;
                                        Inst_Config.Pneu.Aux_4.Functional = FALSE;
                                        Inst_Config.Pneu.Aux_5.Functional = FALSE;
                                        break;
   }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ReadCalib  ( U_INT8 module_number, pCALIB_STRUCT calib, CALIB_STATE *state )

/**end_proto**/
{

static const EXCEPTION Calib_Lost[] = { FI_CALIB_LOST,  BI_CALIB_LOST, FD_CALIB_LOST, BD_CALIB_LOST, PA_CALIB_LOST };


     switch ( (*state = ReadCalibState( module_number )) )
     {
         case FACTORY:
         case USER_DISABLED: if (! ReadFactoryCalib( module_number, calib ) )
                             {
                                 TrashModule( module_number );
                             }

                             break;


        case USER_ENABLED:   if ( ReadUserCalib ( module_number, calib ) )  break;

                             /* intentional fall through */

        default:             /* user calib is invalid, tell user and blow it away */

                             SetNewException( Calib_Lost[ module_number ], 0, 0 );

                             if ( !ScratchUserCalib ( module_number ) || !ReadFactoryCalib( module_number, calib ) )
                             {
                                 TrashModule( module_number );
                             }
                             else
                             {
                                 *state = FACTORY;
                             }
     }

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void LoadInletCalib ( pINLET_STATUS status )

/**end_proto**/
{

     CALIB_STRUCT calib;

     if ( status->Config->Type == JIB )
     {
           /* jills don't have user calibs */

          status->Calib.P_Sensor_Gain   = CALIB_GAIN_SCALING;
          status->Calib.P_Sensor_Offset = 0;
          status->Calib.Calib_Pressure  = 0;

          status->Calib.F_Sensor_Gain   = CALIB_GAIN_SCALING;
          status->Calib.F_Sensor_Offset = 0;
          status->Calib.Calib_Flow      = 0;

          InitializeDateTime( &status->Calib.Calib_Date );
     }
     else
     {
          ReadCalib( status->Module_Number, &calib, &status->Calib.Calib_State );

          if ( !ReadAutoCalOffset ( status, &calib ) )
          {
               TrashModule( status->Module_Number );
               return;
          }

          status->Calib.P_Sensor_Gain   = calib.Pos_1.Gain;
          status->Calib.P_Sensor_Offset = calib.Pos_1.Offset;
          status->Calib.Calib_Pressure  = calib.Pos_1.Value;

          status->Calib.F_Sensor_Gain   = calib.Pos_2.Gain;
          status->Calib.F_Sensor_Offset = calib.Pos_2.Offset;
          status->Calib.Calib_Flow      = calib.Pos_2.Value;

          status->Calib.Calib_Date      = calib.Date;
     }

}

/**begin_proto**/

void SaveInletCalib ( pINLET_STATUS status )

/**end_proto**/
{

     CALIB_STRUCT calib;

     status->Calib.Calib_State = USER_ENABLED;

     calib.Pos_1.Gain   = status->Calib.P_Sensor_Gain;
     calib.Pos_1.Offset = status->Calib.P_Sensor_Offset;
     calib.Pos_1.Value  = status->Calib.Calib_Pressure;

     calib.Pos_2.Gain   = status->Calib.F_Sensor_Gain;
     calib.Pos_2.Offset = status->Calib.F_Sensor_Offset;
     calib.Pos_2.Value  = status->Calib.Calib_Flow;


     SetDateTime( &status->Calib.Calib_Date );
     calib.Date         = status->Calib.Calib_Date;

     if ( !WriteUserCalib( status->Module_Number, &calib ) )
     {
         TrashModule( status->Module_Number );
     }
}

/**begin_proto**/

void SaveInletFactoryCalib ( pINLET_STATUS status )

/**end_proto**/
{

     CALIB_STRUCT calib;

     calib.Pos_1.Gain   = status->Calib.P_Sensor_Gain;
     calib.Pos_1.Offset = status->Calib.P_Sensor_Offset;
     calib.Pos_1.Value  = status->Calib.Calib_Pressure;

     calib.Pos_2.Gain   = status->Calib.F_Sensor_Gain;
     calib.Pos_2.Offset = status->Calib.F_Sensor_Offset;
     calib.Pos_2.Value  = status->Calib.Calib_Flow;

     if ( !WriteFactoryCalib( status->Module_Number, &calib ) )
     {
         TrashModule( status->Module_Number );
     }
}

/**begin_proto**/

void ScratchInletCalib ( pINLET_STATUS status )

/**end_proto**/
{

     if ( !ScratchUserCalib( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadInletCalib ( status );
}

/**begin_proto**/

void DisableInletCalib ( pINLET_STATUS status )

/**end_proto**/
{
     /* can't disable if in factory calib */

     if ( status->Calib.Calib_State == FACTORY ) return;

     if ( !WriteUserCalibDisabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadInletCalib( status );
}

/**begin_proto**/

void EnableInletCalib ( pINLET_STATUS status )

/**end_proto**/
{
     /* can't enable if calib not disabled */

     if ( status->Calib.Calib_State != USER_DISABLED ) return;

     if ( !WriteUserCalibEnabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadInletCalib( status );
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void LoadDetCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    ReadCalib( status->Module_Number, &calib, &status->Calib_State );

    status->Gas_1.Calib.Gain   = calib.Pos_1.Gain;
    status->Gas_1.Calib.Offset = calib.Pos_1.Offset;
    status->Gas_1.Calib.Flow   = calib.Pos_1.Value;

    status->Gas_2.Calib.Gain   = calib.Pos_2.Gain;
    status->Gas_2.Calib.Offset = calib.Pos_2.Offset;
    status->Gas_2.Calib.Flow   = calib.Pos_2.Value;

    status->Gas_3.Calib.Gain   = calib.Pos_3.Gain;
    status->Gas_3.Calib.Offset = calib.Pos_3.Offset;
    status->Gas_3.Calib.Flow   = calib.Pos_3.Value;

    status->Calib_Date         = calib.Date;

}

/**begin_proto**/

void SaveDetCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    status->Calib_State = USER_ENABLED;

    calib.Pos_1.Gain   = status->Gas_1.Calib.Gain;
    calib.Pos_1.Offset = status->Gas_1.Calib.Offset;
    calib.Pos_1.Value  = status->Gas_1.Calib.Flow;

    calib.Pos_2.Gain   = status->Gas_2.Calib.Gain;
    calib.Pos_2.Offset = status->Gas_2.Calib.Offset;
    calib.Pos_2.Value  = status->Gas_2.Calib.Flow;

    calib.Pos_3.Gain   = status->Gas_3.Calib.Gain;
    calib.Pos_3.Offset = status->Gas_3.Calib.Offset;
    calib.Pos_3.Value  = status->Gas_3.Calib.Flow;

    SetDateTime( &status->Calib_Date );
    calib.Date         = status->Calib_Date;

    if ( !WriteUserCalib( status->Module_Number, &calib ) )
    {
       TrashModule( status->Module_Number );
    }

}

/**begin_proto**/

void SaveDetFactoryCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    calib.Pos_1.Gain   = status->Gas_1.Calib.Gain;
    calib.Pos_1.Offset = status->Gas_1.Calib.Offset;
    calib.Pos_1.Value  = status->Gas_1.Calib.Flow;

    calib.Pos_2.Gain   = status->Gas_2.Calib.Gain;
    calib.Pos_2.Offset = status->Gas_2.Calib.Offset;
    calib.Pos_2.Value  = status->Gas_2.Calib.Flow;

    calib.Pos_3.Gain   = status->Gas_3.Calib.Gain;
    calib.Pos_3.Offset = status->Gas_3.Calib.Offset;
    calib.Pos_3.Value  = status->Gas_3.Calib.Flow;

    if ( !WriteFactoryCalib( status->Module_Number, &calib ) )
    {
        TrashModule( status->Module_Number );
    }
}

/**begin_proto**/

void ScratchDetCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{
    if ( !ScratchUserCalib( status->Module_Number ) )
    {
         TrashModule( status->Module_Number );
         return;
    }

    LoadDetCalib ( status );
}

/**begin_proto**/

void DisableDetCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{
     /* can't disable if in factory calib */

     if ( status->Calib_State == FACTORY ) return;

     if ( !WriteUserCalibDisabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadDetCalib( status );
}

/**begin_proto**/

void EnableDetCalib ( pDETECTOR_STATUS status )

/**end_proto**/
{
     /* can't enable if calib is not disabled */

     if ( status->Calib_State != USER_DISABLED ) return;

     if ( !WriteUserCalibEnabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadDetCalib( status );
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void LoadAuxCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    ReadCalib( status->Module_Number, &calib, &status->Calib_State );

    if ( ReadCalibState( status->Module_Number ) != USER_ENABLED )
    {
       /* using factory calib.   Factory calib does not include */
       /* pressure gain terms, so initialize them to unity  */

      calib.Pos_1.Gain = CALIB_GAIN_SCALING;
      calib.Pos_2.Gain = CALIB_GAIN_SCALING;
      calib.Pos_3.Gain = CALIB_GAIN_SCALING;
    }

    status->Aux_3.Calib.Gain   = calib.Pos_1.Gain;
    status->Aux_3.Calib.Offset = calib.Pos_1.Offset;
    status->Aux_3.Calib.Value  = calib.Pos_1.Value;

    status->Aux_4.Calib.Gain   = calib.Pos_2.Gain;
    status->Aux_4.Calib.Offset = calib.Pos_2.Offset;
    status->Aux_4.Calib.Value  = calib.Pos_2.Value;

    status->Aux_5.Calib.Gain   = calib.Pos_3.Gain;
    status->Aux_5.Calib.Offset = calib.Pos_3.Offset;
    status->Aux_5.Calib.Value  = calib.Pos_3.Value;

    status->Calib_Date   = calib.Date;

}

/**begin_proto**/

void SaveAuxCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    status->Calib_State = USER_ENABLED;

    calib.Pos_1.Gain   = Inst_Status.Pneu.Aux.Aux_3.Calib.Gain;
    calib.Pos_1.Offset = Inst_Status.Pneu.Aux.Aux_3.Calib.Offset;
    calib.Pos_1.Value  = Inst_Status.Pneu.Aux.Aux_3.Calib.Value;

    calib.Pos_2.Gain   = Inst_Status.Pneu.Aux.Aux_4.Calib.Gain;
    calib.Pos_2.Offset = Inst_Status.Pneu.Aux.Aux_4.Calib.Offset;
    calib.Pos_2.Value  = Inst_Status.Pneu.Aux.Aux_4.Calib.Value;

    calib.Pos_3.Gain   = Inst_Status.Pneu.Aux.Aux_5.Calib.Gain;
    calib.Pos_3.Offset = Inst_Status.Pneu.Aux.Aux_5.Calib.Offset;
    calib.Pos_3.Value  = Inst_Status.Pneu.Aux.Aux_5.Calib.Value;

    SetDateTime( &status->Calib_Date );
    calib.Date = status->Calib_Date;

    if ( !WriteUserCalib( status->Module_Number, &calib ) )
    {
        TrashModule( status->Module_Number );
    }
}

/**begin_proto**/

void SaveAuxFactoryCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{

    CALIB_STRUCT calib;

    calib.Pos_1.Gain   = Inst_Status.Pneu.Aux.Aux_3.Calib.Gain;
    calib.Pos_1.Offset = Inst_Status.Pneu.Aux.Aux_3.Calib.Offset;
    calib.Pos_1.Value  = Inst_Status.Pneu.Aux.Aux_3.Calib.Value;

    calib.Pos_2.Gain   = Inst_Status.Pneu.Aux.Aux_4.Calib.Gain;
    calib.Pos_2.Offset = Inst_Status.Pneu.Aux.Aux_4.Calib.Offset;
    calib.Pos_2.Value  = Inst_Status.Pneu.Aux.Aux_4.Calib.Value;

    calib.Pos_3.Gain   = Inst_Status.Pneu.Aux.Aux_5.Calib.Gain;
    calib.Pos_3.Offset = Inst_Status.Pneu.Aux.Aux_5.Calib.Offset;
    calib.Pos_3.Value  = Inst_Status.Pneu.Aux.Aux_5.Calib.Value;

    if ( !WriteFactoryCalib( status->Module_Number, &calib ) )
    {
        TrashModule( status->Module_Number );
    }
}

/**begin_proto**/

void ScratchAuxCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{
    if (! ScratchUserCalib( status->Module_Number ) )
    {
        TrashModule ( status->Module_Number );
        return;
    }

    LoadAuxCalib ( status );
}

/**begin_proto**/

void DisableAuxCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{
     /* can't disable if in factory calib */

     if ( status->Calib_State == FACTORY ) return;

     if ( !WriteUserCalibDisabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadAuxCalib( status );
}

/**begin_proto**/

void EnableAuxCalib ( pAUXILIARY_STATUS status )

/**end_proto**/
{
     /* can't Enable if calib is not disabled */

     if ( status->Calib_State != USER_DISABLED ) return;

     if ( !WriteUserCalibEnabled( status->Module_Number ) )
     {
         TrashModule( status->Module_Number );
     }

     LoadAuxCalib( status );
}

/**begin_proto**/

#pragma SECTION UNDO

/**end_proto**/
